//3分钟搭建three场景

//开始
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { TWEEN } from "three/examples/jsm/libs/tween.module.min";
import { loaderModel } from "./threeLoadModel";
import { CSS3DRenderer } from "three/examples/jsm/renderers/CSS3DRenderer";
import $ from "jquery";
//import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
//const gui = new GUI()

let element = undefined;
let width = undefined;
let height = undefined;
let scene = undefined;
let camera = undefined;
let renderer = undefined;
let controls = undefined;
let mouse = {};
let mouseClick = {};
let mouseClickTime = undefined;
let raycaster = undefined;
//灯光
let ambientLight = undefined;
let directLight = undefined;
let textureCube = undefined;
let label3DRender = undefined;
let css3dLabelGroup = undefined;
let aMeiGroup = undefined;
let bMeiGroup = undefined;
let cMeiGroup = undefined;
let dMeiGroup = undefined;
let eMeiGroup = undefined;
let xiaoMeiGroup = undefined;
let material1 = new THREE.MeshPhysicalMaterial({
  color: 0x141a30,
});
let material2 = new THREE.MeshPhysicalMaterial({
  color: 0x000000,
});
let material3 = new THREE.MeshPhysicalMaterial({
  color: 0x404040,
});
// let material4 = new THREE.MeshPhongMaterial({
//   color: 0x141a30,
// });
// let material5 = new THREE.MeshPhongMaterial({
//   color: 0xbde7e8,
// });
export function initThree(id) {
  //创建从vue页面加载three的入口
  THREE.Cache.enabled = true;
  element = document.getElementById(id);
  width = element.clientWidth;
  height = element.clientHeight;
  createGroup();
  //创建场景
  createScene();
  //创建摄像机
  createCamera();
  // createDaySky();
  // createbox();
  //创建灯光,白色环境光，光照强度为1
  createLight();
  //创建渲染器
  createRenderer();
  createControls();
  skyCube();
  css3DRenderer(width, height, element);
  loaderModel(
    scene,
    css3dLabelGroup,
    aMeiGroup,
    bMeiGroup,
    cMeiGroup,
    dMeiGroup,
    eMeiGroup,
    xiaoMeiGroup
  );
}

function createGroup() {
  css3dLabelGroup = new THREE.Group();
  css3dLabelGroup.name = "css3dLabelGroup";
  aMeiGroup = new THREE.Group();
  aMeiGroup.name = "aMeiGroup";
  bMeiGroup = new THREE.Group();
  bMeiGroup.name = "bMeiGroup";
  cMeiGroup = new THREE.Group();
  cMeiGroup.name = "cMeiGroup";
  dMeiGroup = new THREE.Group();
  dMeiGroup.name = "dMeiGroup";
  eMeiGroup = new THREE.Group();
  eMeiGroup.name = "eMeiGroup";
  xiaoMeiGroup = new THREE.Group();
  xiaoMeiGroup.name = "xiaoMeiGroup";
}

function createScene() {
  scene = new THREE.Scene();
  //scene.background = new THREE.Color(0,0,0);
  scene.add(css3dLabelGroup);
  scene.add(aMeiGroup);
  scene.add(bMeiGroup);
  scene.add(cMeiGroup);
  scene.add(dMeiGroup);
  scene.add(eMeiGroup);
  scene.add(xiaoMeiGroup);
}
function createCamera() {
  camera = new THREE.PerspectiveCamera(45, width / height, 1, 80000000);
  camera.position.z = 100;
}

function createLight() {
  // ambientLight = new THREE.AmbientLight(0xffffff, 1);
  // scene.add(ambientLight);
  // const spotLight = new THREE.SpotLight(0xffffff, 5, 1000, Math.PI / 10, 0, 2);
  // spotLight.position.set(100, 1000, 100);
  // spotLight.castShadow = true;

  // spotLight.shadow.mapSize.width = 500;
  // spotLight.shadow.mapSize.height = 500;
  // spotLight.shadow.camera.far = 400;

  // scene.add(spotLight);

  // // const spotLightHelper = new THREE.SpotLightHelper( spotLight );
  // // scene.add( spotLightHelper );
  // //    const light = new THREE.HemisphereLight( 0xffffff, 0x000000, 1 );
  // // light.position.set(0,1000,0)
  // //    scene.add(light);
  directLight = new THREE.DirectionalLight(0xffffff, 0.3);
  scene.add(directLight);
  const light1 = new THREE.DirectionalLight(0xffffff, 0.5);
  light1.position.set(0, 0, 100);
  scene.add(light1);
  //gui.addColor(light1,'color')
  //gui.add(light1,'intensity',0,2)
  const light2 = new THREE.DirectionalLight(0xffffff, 0.5);
  light2.position.set(0, 0, -100);
  scene.add(light2);
  const light3 = new THREE.DirectionalLight(0xffffff, 0.5);
  light3.position.set(100, 0, 0);
  scene.add(light3);
  const light4 = new THREE.DirectionalLight(0xffffff, 0.5);
  light4.position.set(-100, 0, 0);
  scene.add(light4);
  const light5 = new THREE.DirectionalLight(0xffffff, 0.5);
  light5.position.set(0, 100, 0);
  scene.add(light5);
  const light6 = new THREE.DirectionalLight(0xffffff, 0.5);
  light6.position.set(50, 100, 0);
  scene.add(light6);
  const light7 = new THREE.DirectionalLight(0xffffff, 0.5);
  light7.position.set(0, 100, 50);
  scene.add(light7);
  const light8 = new THREE.DirectionalLight(0xffffff, 0.5);
  light8.position.set(0, 100, -50);
  scene.add(light8);
  const light9 = new THREE.DirectionalLight(0xffffff, 0.5);
  light9.position.set(-50, 100, 0);
  scene.add(light9);
}
function createRenderer() {
  renderer = new THREE.WebGLRenderer({
    precision: "highp",
    alpha: true,
    antialias: true,
  });
  renderer.shadowMap.enabled = true;
  renderer.autoClear = true;
  renderer.outputEncoding = THREE.sRGBEncoding; //調整色彩飽和度
  // renderer.physicallyCorrectLights = false;
  // renderer.toneMappingExposure = 0.1;
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(width, height);
  //renderer.setClearColor( 0x263238 );
  //renderer.setPixelRatio(window.devicePixelRatio)
  // renderer.localClippingEnabled = true;
  element.appendChild(renderer.domElement);
  element.addEventListener("pointermove", mouseMove, false);
  element.addEventListener("pointerup", mouseUp, false);
  element.addEventListener("pointerdown", mouseDown, false);
}
function mouseMove() {
  mouse.x =
    ((window.event.clientX - element.getBoundingClientRect().left) /
      element.offsetWidth) *
      2 -
    1;
  mouse.y =
    -(
      (window.event.clientY - element.getBoundingClientRect().top) /
      element.offsetHeight
    ) *
      2 +
    1;
  document.body.style.cursor = "default";
  raycaster = new THREE.Raycaster();
  raycaster.setFromCamera(mouse, camera);
}
function mouseUp() {
  if (window.event.button == 0) {
    if (
      window.event.clientX - mouseClick.x <= 10 &&
      window.event.clientY - mouseClick.y <= 10 &&
      Date.now() - mouseClickTime < 150
    ) {
      raycaster = new THREE.Raycaster();
      raycaster.setFromCamera(mouse, camera);
      //   let intersects = raycaster.intersectObject(scene);
      // console.log(intersects);
    }
  } else if (window.event.button == 2) {
    if (
      window.event.clientX - mouseClick.x <= 5 &&
      window.event.clientY - mouseClick.y <= 5 &&
      Date.now() - mouseClickTime < 150
    ) {
      raycaster = new THREE.Raycaster();
      raycaster.setFromCamera(mouse, camera);
      // initControl();
    }
  }
}
function mouseDown() {
  mouseClick.x = window.event.clientX;
  mouseClick.y = window.event.clientY;
  mouseClickTime = Date.now();
}
function createControls() {
  controls = new OrbitControls(camera, renderer.domElement);
  controls.object.position.set(
    1.6184944433630326,
    77.03718795836723,
    200.7959752529053
  );
  controls.target.set(1.3317309484546325, 73.70139211203436, 49.73186974030818);
  controls.enabled = false;
}
//天空盒子
function skyCube() {
  var r = "static/model/skybox/";
  var urls = [
    r + "nx.jpg",
    r + "ny.jpg",
    r + "nz.jpg",
    r + "px.jpg",
    r + "py.jpg",
    r + "pz.jpg",
  ];

  textureCube = new THREE.CubeTextureLoader().load(urls);
  textureCube.format = THREE.RGBFormat;
  textureCube.mapping = THREE.CubeReflectionMapping;
  //scene.background = textureCube;
}
function css3DRenderer(width, height, element) {
  label3DRender = new CSS3DRenderer();
  label3DRender.setSize(width, height);
  label3DRender.domElement.style.position = "absolute";
  label3DRender.domElement.style.top = "0px";
  label3DRender.domElement.style.pointerEvents = "none";
  element.appendChild(label3DRender.domElement);
}

export function render() {
  TWEEN.update();
  controls.update();
  // console.log(controls.object.position, controls.target);
  // 标签
  if (css3dLabelGroup) {
    let rotate = camera.getWorldDirection(new THREE.Vector3());
    let label = css3dLabelGroup;
    if (label) {
      for (let i = 0; i < label.children.length; i++) {
        for (let j = 0; j < label.children[i].children.length; j++) {
          label.children[i].children[j].rotation.y =
            Math.atan2(rotate.x, rotate.z) + Math.PI;
        }
      }
    }
  }
  directLight.position.x = camera.position.x + 1000;
  directLight.position.y = camera.position.y + 1000;
  directLight.position.z = camera.position.z + 1000;

  if (label3DRender) {
    label3DRender.render(scene, camera);
  }
  renderer.setSize(width, height);
  renderer.render(scene, camera);
  requestAnimationFrame(render);
}

export function initBunkerData(data) {
  if (data.length > 0) {
    data.map((item) => {
      $(`#zongmeiliang_${item.name}`).html(item.mass);
      $(`#time_${item.name}`).html(item.countdown);
      if (item.name == "min") {
        updXiaoMeiGroup(item.name, item);
      } else {
        updMeiGroup(item.name, item);
      }
    });
  }
}

function updMeiGroup(type, item) {
  let height = item.coal_height;
  let showHeight = 0;
  for (let i in height) {
    showHeight += height[i];
    for (let j = 1; j <= height[i]; j++) {
      let num = j < 10 ? "0" + j : j;
      let mesh = undefined;
      if (type == "A") {
        mesh = aMeiGroup.getObjectByName(`${type}_Mei${num}`);
      } else if (type == "B") {
        mesh = bMeiGroup.getObjectByName(`${type}_Mei${num}`);
      } else if (type == "D") {
        mesh = cMeiGroup.getObjectByName(`D_Mei${num}`);
      } else if (type == "C") {
        mesh = dMeiGroup.getObjectByName(`${type}_Mei${num}`);
      } else if (type == "E") {
        mesh = eMeiGroup.getObjectByName(`${type}_Mei${num}`);
      }
      let count = (i % 2) + 1;
      if (mesh && count == 1) {
        mesh.material = material1.clone();
      } else if (mesh && count == 2) {
        mesh.material = material2.clone();
      }
    }
  }
  switch (type) {
    case "A":
      aMeiGroup.children.map((child) => {
        child.visible = false;
        let num = child.name.split("A_Mei")[1];
        if (parseInt(num) <= showHeight) {
          child.visible = true;
        }
      });
      break;
    case "B":
      bMeiGroup.children.map((child) => {
        child.visible = false;
        let num = child.name.split("B_Mei")[1];
        if (parseInt(num) <= showHeight) {
          child.visible = true;
        }
      });
      break;
    case "D":
      dMeiGroup.children.map((child) => {
        let num = child.name.split("D_Mei")[1];
        if (parseInt(num) < 21) {
          child.visible = false;
        }
        if (parseInt(num) <= showHeight) {
          child.visible = true;
        }
      });
      break;
    case "C":
      cMeiGroup.children.map((child) => {
        child.visible = false;
        let num = child.name.split("C_Mei")[1];
        if (parseInt(num) <= showHeight) {
          child.visible = true;
        }
      });
      break;
    case "E":
      eMeiGroup.children.map((child) => {
        child.visible = false;
        let num = child.name.split("E_Mei")[1];
        if (parseInt(num) <= showHeight) {
          child.visible = true;
        }
      });
      break;
    case "min":
      xiaoMeiGroup.children.map((child) => {
        child.visible = false;
        if (showHeight > 0) {
          child.visible = true;
        }
      });
      break;
  }
}

function updXiaoMeiGroup(type, item) {
  let showHeight = item.coal_height;
  const mesh = xiaoMeiGroup.getObjectByName(`XiaoMeiCang_in`);
  let count = (showHeight % 2) + 1;
  if (mesh && count == 1) {
    mesh.material = material1.clone();
  } else if (mesh && count == 2) {
    mesh.material = material2.clone();
  }
  xiaoMeiGroup.children.map((child) => {
    child.visible = false;
    if (showHeight > 0) {
      child.visible = true;
    }
  });
}
